package com.cykj.utils;


import com.cykj.entity.MenuDO;

import java.util.*;


// 菜单列表相关操作
public class TreeMenuUtils {

    // 获取未分配的树形结构菜单
    public static List<MenuDO> getUnAllocateMenu(List<MenuDO> allList, List<MenuDO> hasList) {

        List<MenuDO> unList = new ArrayList<>();          // 存放未分配菜单
        Set<Integer> unListIds = new HashSet<>();           // 存放未分配菜单id

        HashMap<Integer, MenuDO> allMap = new HashMap<>(); // 存放所有菜单
        Set<Integer> hasSet = new HashSet<>();               // 存放已分配的菜单ID

        // 创建Set
        for (MenuDO menu : hasList) {
            hasSet.add(menu.getMenuId());
        }

        // 创建Map
        for (MenuDO menu : allList) {
            allMap.put(menu.getMenuId(), menu);
        }


        // 处理未分配菜单
        for (MenuDO menu : allList) {
            // 跳过已分配菜单
            if (hasSet.contains(menu.getMenuId())) {
                continue;
            }
            // 处理未分配菜单的父级菜单
            Integer parentId = menu.getMenuParentId();                  // 获取父级ID
            while (parentId != 0 && !unListIds.contains(parentId)) {   // 缺失父级则添加
                MenuDO MenuDO = allMap.get(parentId);
                unListIds.add(parentId);                            // 添加到未分配列表中
                parentId = MenuDO.getMenuParentId();              // 往上查找
            }
            unListIds.add(menu.getMenuId());    // 添加到未分配列表中
        }

        // 统一添加到未分配菜单中
        for (Integer menuId : unListIds) {
            unList.add(allMap.get(menuId));
        }

        return getTreeMenu(unList);
    }

    // 获取已分配的树形结构菜单 --> 判断父级菜单是否已分配
    public static List<MenuDO> getAllocateMenu(List<MenuDO> allList, List<MenuDO> hasList) {
        List<MenuDO> allocateMenu = new ArrayList<>();            // 存放已分配菜单
        HashMap<Integer, MenuDO> allMap = new HashMap<>();        // 存放所有菜单
        Set<Integer> hasSet = new HashSet<>();                      // 存放已分配的菜单ID
        // 创建Map
        for (MenuDO menu : allList) {
            allMap.put(menu.getMenuId(), menu);
        }
        // 创建Set
        for (MenuDO menu : hasList) {
            hasSet.add(menu.getMenuId());
        }
        // 处理已分配菜单
        for (MenuDO menu : hasList) {
            Integer parentId = menu.getMenuParentId(); // 获取父级ID
            while (parentId != 0 && !hasSet.contains(parentId)) {
                MenuDO MenuDO = allMap.get(parentId); // 获取父级菜单
                hasSet.add(parentId);                   // 添加到已分配列表中
                parentId = MenuDO.getMenuParentId();  // 往上查找
            }
            hasSet.add(menu.getMenuId());   // 添加到已分配列表中
        }
        // 统一添加到已分配菜单中
        for (Integer menuId : hasSet) {
            allocateMenu.add(allMap.get(menuId));
        }
        return TreeMenuUtils.getTreeMenu(allocateMenu);
    }
    

    // 获取树形结构
    private static List<MenuDO> getTreeMenu(List<MenuDO> menuDOList) {
        List<MenuDO> treeMenu = new ArrayList<>();
        Map<Integer, MenuDO> menuMap = new HashMap<>();

        // 先将所有菜单放入Map中
        for (MenuDO menu : menuDOList) {
            menuMap.put(menu.getMenuId(), menu);
            // 初始化子菜单列表
            if (menu.getChildren() == null) {
                menu.setChildren(new ArrayList<>());
            }
        }

        // 构建树形结构
        for (MenuDO menu : menuDOList) {
            Integer parentId = menu.getMenuParentId();
            if (parentId == 0) {
                // 顶级菜单
                treeMenu.add(menu);
            } else {
                // 子菜单
                MenuDO parent = menuMap.get(parentId);
                if (parent != null) {
                    parent.getChildren().add(menu);
                }
            }
        }
        return treeMenu;
    }

}
